package org.xinjiang.data.migration.common.utils.query;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.xinjiang.data.migration.common.response.PageInfo;
import org.xinjiang.data.migration.common.response.Param;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 分页帮助类
 *
 * @author linkai
 * @date 2022/11/25
 */
public interface Pages {

    String ID = "id";

    static <T> Page<T> page(Param param, OrderItem defaultOrder) {
        Page<T> page = page(param);
        if (defaultOrder != null && CollectionUtils.isEmpty(page.orders())) {
            page.setOrders(ImmutableList.of(defaultOrder));
        }
        return page;
    }

    static <T> Page<T> page(Param param) {
        if (param.getPageNum() == null) {
            param.setPageNum(Param.PAGE_NUM);
        }
        if (param.getPageSize() == null) {
            param.setPageSize(Param.PAGE_SIZE);
        } else if (param.getPageSize() > Param.MAX_PAGE_SIZE) {
            param.setPageSize(Param.MAX_PAGE_SIZE);
        }
        Page<T> page = new Page<>(param.getPageNum(), param.getPageSize());
        page.setOrders(getOrderBy(param));
        return page;
    }

    static List<OrderItem> getOrderBy(Param param) {
        List<String> sorts = param.getSorts();
        if (CollectionUtils.isEmpty(sorts)) {
            return null;
        }
        List<OrderItem> orderItems = Lists.newArrayList();
        for (String v : sorts) {
            if (v.toLowerCase().contains("select") ||
                    v.toLowerCase().contains("union") ||
                    v.toLowerCase().contains("table") ||
                    v.toLowerCase().contains("database") ||
                    v.toLowerCase().contains(";") ||
                    v.toLowerCase().contains("from") ||
                    v.toLowerCase().contains("delete") ||
                    v.toLowerCase().contains("%") ||
                    v.toLowerCase().contains("'") ||
                    v.toLowerCase().contains("floor")) {
                continue;
            }
            String[] split = null;
            if (v.contains(",")) {
                split = v.split(",");
            } else {
                split = v.split("\\|");
            }
            if (split.length > 1) {
                if (StringUtils.equalsIgnoreCase(split[1], "desc")) {
                    orderItems.add(OrderItem.desc(split[0]));
                } else {
                    orderItems.add(OrderItem.asc(split[0]));
                }
            } else {
                orderItems.add(OrderItem.asc(split[0]));
            }
        }
        return orderItems;
    }

    static <T, R> PageInfo<R> convert(IPage<T> page, Function<T, R> func) {
        PageInfo<R> pageInfo = new PageInfo<>();
        if (func != null && CollectionUtils.isNotEmpty(page.getRecords())) {
            pageInfo.setRows(
                    page.getRecords().stream().map(func).collect(Collectors.toList())
            );
        }
        pageInfo.setTotal(page.getTotal());
        pageInfo.setPageNum(page.getCurrent());
        pageInfo.setPageSize(page.getSize());
        return pageInfo;
    }

    static <T> PageInfo<T> convert(IPage<T> page) {
        PageInfo<T> pageInfo = new PageInfo<>();
        pageInfo.setRows(page.getRecords());
        pageInfo.setTotal(page.getTotal());
        pageInfo.setPageNum(page.getCurrent());
        pageInfo.setPageSize(page.getSize());
        return pageInfo;
    }
}
